package com.gxa.sso.service.impl;

import com.gxa.sso.controller.UserController;
import com.gxa.sso.entity.User;
import com.gxa.sso.exception.BusinessException;
import com.gxa.sso.repository.UserRepository;
import com.gxa.sso.service.UserService;
import com.gxa.sso.utils.JsonUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Service("userService")
public class UserServiceImpl implements UserService {


    @Resource
    RedisTemplate redisTemplate;

    @Resource
    UserRepository userRepository;

    @Autowired
    HttpServletRequest request;

    private static final String LOGIN_TOKEN = "TanFu$She1ngShua2iDeY3iPi:";

    @Override
    public Map<String, String> login(String phone, String code) throws BusinessException {

        // 处理短信验证
        //1.获取redis服务器存储的验证码
        Object smsCode = redisTemplate.opsForValue().get(SmsServiceImpl.LOGIN_SMS+phone);

        //2.验证码失效的判断,如果为空则抛出异常
        if(StringUtils.isEmpty(smsCode)){
            throw new BusinessException("验证码不存在或已过期");
        }

        //3.对验证码做校验, 如果不一致则抛出异常
        if(!code.equals(smsCode)){
            throw new BusinessException("验证码验证不通过,请稍后再试");
        }

        //校验完成, 从mysql数据库中查找用户信息
        // 使用JPA完成查询: 通过手机号
        User user = userRepository.findByPhone(phone);

        // 删除验证码
        //redisTemplate.delete(SmsServiceImpl.LOGIN_SMS+phone);

        //如果用户不存在, 则匿名注册,匿名格式: "用户:"+phone , 并指定用户状态
        if(user == null){
            user = new User();
            user.setName("用户"+phone);
            user.setStatus(1);
            user.setPhone(phone);

        }

        // userbyPhone对象非空表示用户对象存在, 判断status
        if(user.getStatus() != 1){
            throw new BusinessException("登录失败,账号为解冻,请联系管理员,或发送邮件admin@eshop.com");
        }

        // 判断如果用户存储的redis中的token信息还在(没有过期)
        // 只能从数据库中查询
        redisTemplate.delete(LOGIN_TOKEN+user.getToken());

        //生成token，存储登录信息(json),利用处理后的UUID
        String token = UUID.randomUUID().toString().replace("-", "");
        // 把token添加到对象中
        user.setToken(token);

        // 用户的状态:
        // 用户的最后一次登录时间
        user.setLastLoginTime(new Date());
        // 用户的访问ip地址(beanFactory)
        user.setIpAddress(request.getRemoteAddr());



        // 完成持久化
        User save = userRepository.save(user);


        // 处理token
        //redisTemplate.opsForValue().set("token",token,30, TimeUnit.MINUTES);
        //        key: 经过密钥组合加工了token
//        value: 放经过json转换的用户信息
        String key = LOGIN_TOKEN+token;
        String value = JsonUtils.objectToJson(user);
        redisTemplate.opsForValue().set(key,value,30,TimeUnit.MINUTES);

        Map<String,String> result = new HashMap<>();
        result.put("token",token);
        return result;
    }

    @Override
    public User validateToken(String token) throws BusinessException {

        String key = LOGIN_TOKEN+token;

        // 从redis中获取token对应的key
        Object tokenKey = redisTemplate.opsForValue().get(key);

        if( StringUtils.isEmpty(tokenKey)){
            throw new BusinessException("没有查到用户信息或者token已经过期,请检查或重新登录");
        }

        return JsonUtils.jsonToObject(tokenKey.toString(),User.class);
    }


}
